package study.elasticsearch.repository.impl;

import com.alibaba.fastjson.JSONObject;
import factory.SourceInfo;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.metrics.avg.Avg;
import org.elasticsearch.search.aggregations.metrics.avg.AvgAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import study.elasticsearch.repository.BbsSearchRepository;

import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Repository
public class BbsSearchImpl implements BbsSearchRepository {
    @Autowired
    RestHighLevelClient restHighLevelClient;


    @Override
    public String search(SourceInfo info) {
        SearchRequest searchRequest = new SearchRequest(info.getIndex());
        SearchSourceBuilder builder = new SearchSourceBuilder();
        searchRequest.source(builder.query(QueryBuilders.matchAllQuery()));
        try {
            SearchResponse resp = restHighLevelClient.search(searchRequest);
            SearchHit[] hits = resp.getHits().getHits();
            return JSONObject.toJSONString(hits);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String limitSearch(SourceInfo info) {
        SearchRequest searchRequest = new SearchRequest(info.getIndex());
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.termQuery("tid",10011));
        builder.from(0).size(5);
        builder.timeout(new TimeValue(60,TimeUnit.SECONDS));
        String[] includes = {"tid","author"};
        FetchSourceContext fetchSourceContext = new FetchSourceContext(true,includes,null);
        builder.fetchSource(fetchSourceContext);
        searchRequest.source(builder);
        try {
            SearchResponse resp = restHighLevelClient.search(searchRequest);
            SearchHit[] hits = resp.getHits().getHits();
            return JSONObject.toJSONString(hits);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String sortSearch(SourceInfo info) {
        SearchRequest searchRequest = new SearchRequest(info.getIndex());
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchAllQuery());
        builder.sort(new FieldSortBuilder("_id").order(SortOrder.DESC));
        searchRequest.source(builder);
        try {
            SearchResponse resp = restHighLevelClient.search(searchRequest);
            SearchHit[] hits = resp.getHits().getHits();
            return JSONObject.toJSONString(hits);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String highLightSearch(SourceInfo info) {
        SearchRequest searchRequest = new SearchRequest(info.getIndex());
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        HighlightBuilder builder = new HighlightBuilder();
        // 设置高亮
        HighlightBuilder.Field highlightAuthor = new HighlightBuilder.Field("author");
        highlightAuthor.preTags("<span style=\"color:#red\">");
        highlightAuthor.postTags("<span>");
        highlightAuthor.highlighterType("unified");
        HighlightBuilder.Field highlighttid = new HighlightBuilder.Field("tid");
        highlightAuthor.highlighterType("unified");
        builder.field(highlightAuthor);
        builder.field(highlighttid);
        sourceBuilder.highlighter(builder);
        sourceBuilder.query(QueryBuilders.matchQuery("tid","夏洛特"));
        searchRequest.source(sourceBuilder);
        try {
            SearchResponse resp = restHighLevelClient.search(searchRequest);
            SearchHit[] hits = resp.getHits().getHits();
            for (SearchHit hit : hits) {
                Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                Text[] authors = highlightFields.get("author").getFragments();
                String text = authors[0].string();
                System.out.println(text);
                System.out.println(Arrays.toString(authors));
            }
            return JSONObject.toJSONString(hits);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String aggSearch(SourceInfo info) {
        SearchRequest request = new SearchRequest(info.getIndex());
        SearchSourceBuilder builder = new SearchSourceBuilder();
        AvgAggregationBuilder field = AggregationBuilders.avg("age_avg").field("age");
        builder.aggregation(field);
        request.source(builder);
        try {
            SearchResponse resp = restHighLevelClient.search(request);
            Aggregations aggregations = resp.getAggregations();
            Avg avg = aggregations.get("age_avg");
            return String.valueOf(avg.getValue());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}
